#ifndef RSIM_UTILS_H
#define RSIM_UTILS_H

/* --------------------------------------------------------------------------*
* File: Utils.h                                                              *
* Authors: Kishor Bhalerao                                                   *
* Email : kishor8dm@gmail.com                                                *
* Contributors:                                                              *
* Email:                                                                     *
* copyright (c) 2010 Authors.                                                *
*                                                                            *
* This program is free software: you can redistribute it and/or modify it    *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or any later version.*
*                                                                            *
* This program is distributed in the hope that it will be useful, but        *
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
* or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License   *
* for more details. (http://www.gnu.org/licenses/)                           *
* -------------------------------------------------------------------------- */

#include "LinAlgDecl.h"
#include "List.h"

#include <iostream>
#include <string>
using namespace std;

namespace RSIM{

// General Utility functions.
namespace Utils{
        /** calculates the RMS value of a given vector */
        void calcRMS(const Vector& V, double& rms);
        
        /** returns the element of the vector with the largest magnitude */
        double abs_max(const Vector& V);
                
        /** assert that condition is true else print error message */
        void rsim_assert(bool condition,string error_string);
        
        /** Calculate the 2 norm of vector. */
        double norm(const Vector& v);
        
        /** Solves the equations Ax = B where A is a diagonal matrix with all entries as
        non-zero. Dimensions must be consistent. No checks performed.*/
        void solve(const Matrix& A, const Vector& B, Vector& X);
        
        /** Normalize the given vector v. len is the length of the vector. No error checks
        in this function.*/
        void normalize(const double& len, double *v);
        
        /** Calculated the weighted norm of a given vector v with weights specified by w.
        The length of vectors v and w should be the same. The output of this function is 
        norm = sqrt( \sum_i {w_i * v_i * v_i} ) */
        double weighted_norm(const Vector& v, const Vector& w);                
        
        /** If the given element is found in the list, the function returns the index
        of the element in the list. If not found, the function returns -1.*/
        template <class T>
        int findElementInList(const List<T>& L, const T& Element){                
                const int& len = L.getLength();
                for(int i=0;i<len;++i){
                        if(L.getElement(i)==Element)                        
                                return i;
                }
                return -1;
        }
        
        /** Display a 2D List. Note: class T should have an operator << otherwise
        the function will not work. */
        template <class T>
        void display2DList(const List<List<T> >& list){
                for(int i=0;i<list.getLength();++i){
                        for(int j=0;j<list[i].getLength();++j)
                                cout<<list[i][j]<<"\t";
                        cout<<endl;
                }                
        }
        
        /** Display a 1D List. Note: class T should have an operator << otherwise
        the function will not work. */
        template <class T>
        void display1DList(const List<T>& list){
                for(int i=0;i<list.getLength();++i)
                        cout<<list[i]<<"\t";
                cout<<endl;
        }                
} // Namespace Utils

} // namespace RSIM

#endif